\section{Casos De Prueba}
\subsection{Tests.hs}
\scriptsize
\begin{verbatim}
import Tablero
import Damas
import HUnit
import Maybe
import Char

-- evaluar t para correr todos los tests
t = runTestTT allTests

allTests = test [ 
    "tablero" ~: testsTablero,
    "arbol" ~: testsArbol,
    "damas" ~: testsDamas,
    "comer con fichas simples" ~: testsComerSimple,
    "comer con fichas reina" ~: testsComerReina,
    "convertir moviendo" ~: testConvertirReina,
    "convertir comiendo" ~: testConvertirReinaComiendo,
    "movimientos posibles" ~: testMovimientosPosibles,
    "ganador" ~: testsGanador
	]


-- Tests del tablero
testsTablero = test [
    (Nothing) ~=? (contenido (a_1) vacio),
    (Just (Simple Negra)) ~=? (contenido (a_1) (poner (a_1) (Simple Negra) vacio)),
    (Nothing) ~=? (contenido (a_1) (sacar (a_1) (poner (a_1) (Simple Negra) vacio)))
    ]

testsComerSimple = test [
	--compruebo que no hay nada antes de mover la blanca
	(Nothing) ~=? (contenido (b_6) (tabBlancaRodeada)),
	(Nothing) ~=? (contenido (f_6) (tabBlancaRodeada)),
	--compruebo que hay una ficha en la direccion que voy a mover
	(Just _n) ~=? (contenido (c_5) (tabBlancaRodeada)),
	(Just _n) ~=? (contenido (e_5) (tabBlancaRodeada)),
	--compruebo que no puedo mover la blanca para abajo
	(True) ~=? isNothing(mover (M (d_4) BL) (J Blanca tabBlancaRodeada)),
	(True) ~=? isNothing(mover (M (d_4) BR) (J Blanca tabBlancaRodeada)),
	--compruebo que se movio la ficha blanca en la direccion que queria
	(Just _b) ~=? (contenidoJuego (b_6) (dameJuego (mover (M (d_4) TL) (J Blanca tabBlancaRodeada)))),
	(Just _b) ~=? (contenidoJuego (f_6) (dameJuego (mover (M (d_4) TR) (J Blanca tabBlancaRodeada)))),
	--compruebo que se comio la ficha negra
	(Nothing) ~=? (contenidoJuego (c_5) (dameJuego (mover (M (d_4) TL) (J Blanca tabBlancaRodeada)))),
	(Nothing) ~=? (contenidoJuego (e_5) (dameJuego (mover (M (d_4) TR) (J Blanca tabBlancaRodeada))))
	]

testsComerReina = test [
	--compruebo que no hay nada antes de mover la blanca
	(Nothing) ~=? (contenido (b_6) (tabReinaRodeadaReinas )),
	(Nothing) ~=? (contenido (f_6) (tabReinaRodeadaReinas )),
	(Nothing) ~=? (contenido (b_2) (tabReinaRodeadaReinas )),
	(Nothing) ~=? (contenido (f_2) (tabReinaRodeadaReinas )),
	--compruebo que hay una ficha en la direccion que voy a mover
	(Just _N) ~=? (contenido (c_5) (tabReinaRodeadaReinas )),
	(Just _N) ~=? (contenido (e_5) (tabReinaRodeadaReinas )),
	(Just _N) ~=? (contenido (c_3) (tabReinaRodeadaReinas )),
	(Just _N) ~=? (contenido (e_3) (tabReinaRodeadaReinas )),
	--compruebo que se movio la ficha blanca en cualquier direccion
	(Just _B) ~=? (contenidoJuego (b_6) (dameJuego (mover (M (d_4) TL) (J Blanca tabReinaRodeadaReinas )))),
	(Just _B) ~=? (contenidoJuego (f_6) (dameJuego (mover (M (d_4) TR) (J Blanca tabReinaRodeadaReinas )))),
	(Just _B) ~=? (contenidoJuego (b_2) (dameJuego (mover (M (d_4) BL) (J Blanca tabReinaRodeadaReinas )))),
	(Just _B) ~=? (contenidoJuego (f_2) (dameJuego (mover (M (d_4) BR) (J Blanca tabReinaRodeadaReinas )))),
	--compruebo que se comio la ficha negra
	(Nothing) ~=? (contenidoJuego (c_5) (dameJuego (mover (M (d_4) TL) (J Blanca tabReinaRodeadaReinas )))),
	(Nothing) ~=? (contenidoJuego (e_5) (dameJuego (mover (M (d_4) TR) (J Blanca tabReinaRodeadaReinas )))),
	(Nothing) ~=? (contenidoJuego (c_3) (dameJuego (mover (M (d_4) BL) (J Blanca tabReinaRodeadaReinas )))),
	(Nothing) ~=? (contenidoJuego (e_3) (dameJuego (mover (M (d_4) BR) (J Blanca tabReinaRodeadaReinas ))))
	]

testConvertirReina = test [
	--compruebo que no hay nada antes de mover la blanca
	(Just _b) ~=? (contenido (c_7) (tabConviertoReinaBlanca )),
	(Nothing) ~=? (contenido (b_8) (tabConviertoReinaBlanca )),
	(Nothing) ~=? (contenido (d_8) (tabConviertoReinaBlanca )),
	--compruebo que se movio la ficha blanca en cualquier direccion y se convierte en reina
	(Just _B) ~=? (contenidoJuego (b_8) (dameJuego (mover (M (c_7) TL) (J Blanca tabConviertoReinaBlanca )))),
	(Just _B) ~=? (contenidoJuego (d_8) (dameJuego (mover (M (c_7) TR) (J Blanca tabConviertoReinaBlanca ))))
	]

testConvertirReinaComiendo = test [
	--compruebo que no hay nada antes de mover la blanca
	(Just _b) ~=? (contenido (d_6) (tabConviertoReinaBlancaComiendo )),
	(Just _n) ~=? (contenido (c_7) (tabConviertoReinaBlancaComiendo )),
	(Just _n) ~=? (contenido (e_7) (tabConviertoReinaBlancaComiendo )),
	(Nothing) ~=? (contenido (b_8) (tabConviertoReinaBlancaComiendo )),
	(Nothing) ~=? (contenido (f_8) (tabConviertoReinaBlancaComiendo )),
	--compruebo que se movio la ficha blanca en cualquier direccion y se convierte en reina
	(Just _B) ~=? (contenidoJuego (b_8) (dameJuego (mover (M (d_6) TL) (J Blanca tabConviertoReinaBlancaComiendo )))),
	(Nothing) ~=? (contenidoJuego (c_7) (dameJuego (mover (M (d_6) TL) (J Blanca tabConviertoReinaBlancaComiendo )))),
	(Just _B) ~=? (contenidoJuego (f_8) (dameJuego (mover (M (d_6) TR) (J Blanca tabConviertoReinaBlancaComiendo )))),
	(Nothing) ~=? (contenidoJuego (e_7) (dameJuego (mover (M (d_6) TR) (J Blanca tabConviertoReinaBlancaComiendo ))))
	]

testMovimientosPosibles = test [
	[(('d',4),TL),(('d',4),TR)] ~=? (listaMovimientosSinJuego (J Blanca tabBlancaRodeada)),
	[(('d',4),TL),(('d',4),TR)] ~=? (listaMovimientosSinJuego (J Blanca tabBlancaRodeadaReinas)),
	[(('d',4),TL),(('d',4),TR),(('d',4),BL),(('d',4),BR)] ~=? (listaMovimientosSinJuego (J Blanca tabReinaRodeada ))
	]

testsGanador = test [    
    (Just Negra) ~=? (ganador (J Blanca vacio)),
    (Just Blanca) ~=? (ganador (J Negra vacio)),
    (Just Negra) ~=? (ganador (J Blanca (poner (a_1) (Simple Negra) (poner (b_8) (Simple Blanca) vacio)))),
    (Nothing) ~=? (ganador (J Blanca (poner (a_7) (Simple Blanca) (poner (a_1) (Simple Negra) vacio)))),
    (Nothing) ~=? (ganador (J Blanca (poner (a_1) (Simple Blanca) (poner (a_7) (Simple Negra) vacio))))
	]

testsArbol = test [
    1 ~=? altura (podar 0 arbolDeIntAltura4),
    2 ~=? altura (podar 1 arbolDeIntAltura4),
    3 ~=? altura (podar 2 arbolDeIntAltura4),
    71 ~=? (sumaArbol arbolDeIntAltura4)
    ]

testsDamas = test [
    (Reina Blanca) ~=? coronarSiSeDebe (Simple Blanca) (b_8),
    (Simple Blanca) ~=? coronarSiSeDebe (Simple Blanca) (b_4),
    (Simple Negra) ~=? coronarSiSeDebe (Simple Negra) (b_8),
    (Reina Negra) ~=? coronarSiSeDebe (Simple Negra) (b_1)
    ]


-- ejemplos para testear al arbol
altura :: Arbol a -> Int
altura = foldArbol f max0
    where 
        f = \_ y -> 1 + y
        max0 = foldr max 0

sumaArbol :: Arbol Integer -> Integer
sumaArbol = foldArbol s s2
    where 
        s = \x y -> x + y
        s2 = foldr s 0


-- idem ~=? pero sin importar el orden
(~~?) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Test
expected ~~? actual = (sort expected) ~=? (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

(~~) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Bool
expected ~~ actual = (sort expected) == (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

-- constantes para que los tests sean más legibles		
_n = Simple Negra
_N = Reina Negra
_b = Simple Blanca
_B = Reina Blanca
a_1 = ('a',1::Int)
b_1 = ('b',1::Int)
c_1 = ('c',1::Int)
d_1 = ('d',1::Int)
e_1 = ('e',1::Int)
f_1 = ('f',1::Int)
g_1 = ('g',1::Int)
h_1 = ('h',1::Int)

a_2 = ('a',2::Int)
b_2 = ('b',2::Int)
c_2 = ('c',2::Int)
d_2 = ('d',2::Int)
e_2 = ('e',2::Int)
f_2 = ('f',2::Int)
g_2 = ('g',2::Int)
h_2 = ('h',2::Int)

a_3 = ('a',3::Int)
b_3 = ('b',3::Int)
c_3 = ('c',3::Int)
d_3 = ('d',3::Int)
e_3 = ('e',3::Int)
f_3 = ('f',3::Int)
g_3 = ('g',3::Int)
h_3 = ('h',3::Int)

a_4 = ('a',4::Int)
b_4 = ('b',4::Int)
c_4 = ('c',4::Int)
d_4 = ('d',4::Int)
e_4 = ('e',4::Int)
f_4 = ('f',4::Int)
g_4 = ('g',4::Int)
h_4 = ('h',4::Int)

a_5 = ('a',5::Int)
b_5 = ('b',5::Int)
c_5 = ('c',5::Int)
d_5 = ('d',5::Int)
e_5 = ('e',5::Int)
f_5 = ('f',5::Int)
g_5 = ('g',5::Int)
h_5 = ('h',5::Int)

a_6 = ('a',6::Int)
b_6 = ('b',6::Int)
c_6 = ('c',6::Int)
d_6 = ('d',6::Int)
e_6 = ('e',6::Int)
f_6 = ('f',6::Int)
g_6 = ('g',6::Int)
h_6 = ('h',6::Int)

a_7 = ('a',7::Int)
b_7 = ('b',7::Int)
c_7 = ('c',7::Int)
d_7 = ('d',7::Int)
e_7 = ('e',7::Int)
f_7 = ('f',7::Int)
g_7 = ('g',7::Int)
h_7 = ('h',7::Int)

a_8 = ('a',8::Int)
b_8 = ('b',8::Int)
c_8 = ('c',8::Int)
d_8 = ('d',8::Int)
e_8 = ('e',8::Int)
f_8 = ('f',8::Int)
g_8 = ('g',8::Int)
h_8 = ('h',8::Int)

arbolDeIntAltura4 = Nodo 2 [Nodo 3 [Nodo 6 [Nodo 60 []]]]







--la blanca se puede mover a 2 lugares, hacia arriba 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |n| |n| | | | 5
--4 | | | |b| | | | | 4
--3 | | |n| |n| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabBlancaRodeada = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Simple Blanca)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Simple Negra)
						else Nothing
				)

--la blanca se puede mover a 2 lugares, hacia arriba 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |N| |N| | | | 5
--4 | | | |b| | | | | 4
--3 | | |N| |N| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabBlancaRodeadaReinas = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Simple Blanca)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Reina Negra)
						else Nothing
				)

--la blanca se puede mover a 2 lugares, hacia abajo 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |b| |b| | | | 5
--4 | | | |n| | | | | 4
--3 | | |b| |b| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabNegraRodeada = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Simple Negra)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Simple Blanca)
						else Nothing
				)

--la blanca se puede mover a 2 lugares, hacia abajo 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |B| |B| | | | 5
--4 | | | |n| | | | | 4
--3 | | |B| |B| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabNegraRodeadaReinas = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Simple Negra)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Reina Blanca)
						else Nothing
				)











--la blanca se puede mover a 4 lugares, hacia arriba y abajo 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |n| |n| | | | 5
--4 | | | |B| | | | | 4
--3 | | |n| |n| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabReinaRodeada = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Reina Blanca)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Simple Negra)
						else Nothing
				)

--la blanca se puede mover a 4 lugares, hacia arriba y abajo 
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | |N| |N| | | | 5
--4 | | | |B| | | | | 4
--3 | | |N| |N| | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabReinaRodeadaReinas = T (\(c,i)-> if (c == 'd' && i == 4) then Just (Reina Blanca)
						else if ((c == 'c'||c == 'e') && (i == 3|| i == 5)) then Just (Reina Negra)
						else Nothing
				)

--Solo muevo para arriba y es reina, 2 movimientos posibles B8 D8
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | |b| | | | | | 7
--6 | | | | | | | | | 6
--5 | | | | | | | | | 5
--4 | | | | | | | | | 4
--3 | | | | | | | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabConviertoReinaBlanca = T 	(\(c,i)-> if (c == 'c' && i == 7)
				then Just (Simple Blanca)
				else Nothing
				)

--Solo muevo para abajo y es reina, 2 movimientos posibles A1 C1
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | | | | | | | | 5
--4 | | | | | | | | | 4
--3 | | | | | | | | | 3
--2 | |n| | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabConviertoReinaNegra = T 	(\(c,i)-> if (c == 'b' && i == 2)
				then Just (Simple Negra)
				else Nothing
				)







--Solo muevo para arriba, como y es reina, 2 movimientos posibles B8 D8
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | |n| |n| | | | 7
--6 | | | |b| | | | | 6
--5 | | | | | | | | | 5
--4 | | | | | | | | | 4
--3 | | | | | | | | | 3
--2 | | | | | | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabConviertoReinaBlancaComiendo = T (\(c,i)-> if (c == 'd' && i == 6) then Just (Simple Blanca)
						else if ((c == 'c'||c == 'e') && (i == 7)) then Just (Simple Negra)
						else Nothing
						)

--Solo muevo para abajo, como y es reina, 2 movimientos posibles A1 C1
--   a b c d e f g h  
--  ----------------- 
--8 | | | | | | | | | 8
--7 | | | | | | | | | 7
--6 | | | | | | | | | 6
--5 | | | | | | | | | 5
--4 | | | | | | | | | 4
--3 | | |n| | | | | | 3
--2 | |b| |b| | | | | 2
--1 | | | | | | | | | 1
--  ----------------- 
--   a b c d e f g h  
tabConviertoReinaNegraComiendo = T (\(c,i)-> if (c == 'c' && i == 3) then Just (Simple Negra)
						else if ((c == 'b'||c == 'd') && (i == 2)) then Just (Simple Blanca)
						else Nothing
						)

--funciones auxiliares para los tests
contenidoJuego :: Posicion -> Juego -> Maybe Ficha
contenidoJuego p (J c t) = contenido p t

dameJuego :: Maybe Juego -> Juego
dameJuego (Just j) = j

listaMovimientosSinJuego :: Juego -> [(Posicion, Direccion)]
listaMovimientosSinJuego j = map (\((M p d),b) -> (p,d)) (movimientosPosibles j)

\end{verbatim}
\normalsize

